﻿//  --------------------------------
//  Copyright (c) AW Systems, Inc. All rights reserved.
//  This source code is made available under the terms of the Microsoft Public License (Ms-PL)
//  http://www.codeplex.com/SLAM/license
//  ---------------------------------

using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Reflection;
using System.Threading;
using System.Web;
using Slam.Configuration;
using Slam.Logging;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using Slam.FieldTypes;

namespace Slam.SharePoint
{
	public class SharePointServices
	{
		#region Private State
		
		private ILogger _logger;
		private int _sequenceNumber;

		#endregion

		#region Constructors

		public SharePointServices(ILogger logger)
		{
			_logger = logger;
			_sequenceNumber = 200;
		}

		#endregion

		public void AddSlamIdFieldToContentType(string siteCollectionUrl, string siteName, string contentTypeName)
		{
			using (SPSite siteCollection = new SPSite(siteCollectionUrl))
			{
				SPWeb site = null;
				SPWeb rootSite = siteCollection.RootWeb;
				if (!String.IsNullOrEmpty(siteName))
				{
					try
					{
						site = siteCollection.AllWebs[siteName];
					}
					catch { }
				}
				else
				{
					site = siteCollection.RootWeb;
				}

				if (site != null && site.Exists)
				{
					SPContentType contentType = null;

					try
					{
						contentType = site.ContentTypes[contentTypeName];
					}
					catch
					{
						//content type not found
					}

					if (contentType != null && !contentType.Sealed)
					{
						if (contentType.FieldLinks["SLAM_x0020_ID"] != null && !contentType.Fields.ContainsFieldWithStaticName("SLAM_x0020_ID"))
						{
							contentType.FieldLinks.Delete("SLAM_x0020_ID");

							try
							{
								site.AllowUnsafeUpdates = true;
								contentType.Update(true);
							}
							catch (Exception ex)
							{
								//SharePoint has this wonderful feature that enables us to not
								//check whether a Content Type has children.  If it does not
								//the above Update will throw an exception.  If it is does, the following
								//will not work the way we want.
								contentType.Update();
							}
						}

						if (contentType.FieldLinks["SLAM_x0020_ID"] == null)
						{
							if (!rootSite.Fields.ContainsField("SLAM ID"))
							{
								rootSite.AllowUnsafeUpdates = true;

								SlamIdField newField = (SlamIdField)rootSite.Fields.CreateNewField("SlamIdField", "SLAM ID");
								newField.ShowInForms = false;
								newField.GenerateValue = true;
								rootSite.Fields.Add(newField);
								Thread.Sleep(800);
							}

							site.AllowUnsafeUpdates = true;
							contentType.FieldLinks.Add(new SPFieldLink(rootSite.Fields["SLAM ID"]));

							try
							{
								site.AllowUnsafeUpdates = true;
								contentType.Update(true);
							}
							catch (Exception ex)
							{
								//SharePoint has this wonderful feature that enables us to not
								//check whether a Content Type has children.  If it does not
								//the above Update will throw an exception.  If it is does, the following
								//will not work the way we want.
								contentType.Update();
							}
						}
					}
				}

				site.Dispose();
				rootSite.Dispose();
			}
		}

		public void AddSlamIdFieldToList(string siteCollectionUrl, string siteName, string listId, string listName)
		{
			using (SPSite siteCollection = new SPSite(siteCollectionUrl))
			{
				SPWeb site = null;
				SPWeb rootSite = siteCollection.RootWeb;
				if (!String.IsNullOrEmpty(siteName))
				{
					try
					{
						site = siteCollection.AllWebs[siteName];
					}
					catch { }
				}
				else
				{
					site = siteCollection.RootWeb;
				}

				SPList list = null;

				if (site != null && site.Exists)
				{
					site.AllowUnsafeUpdates = true;

					try
					{
						if (!String.IsNullOrEmpty(listId))
						{
							list = site.Lists[new Guid(listId)];
						}
						else
						{
							list = site.Lists[listName];
						}
					}
					catch { }

					if (list != null && !list.Fields.ContainsField("SLAM ID"))
					{
						if (!rootSite.Fields.ContainsField("SLAM ID"))
						{
							rootSite.AllowUnsafeUpdates = true;

							SlamIdField newField = (SlamIdField)rootSite.Fields.CreateNewField("SlamIdField", "SLAM ID");
							newField.ShowInForms = false;
							newField.GenerateValue = true;
							rootSite.Fields.Add(newField);
							Thread.Sleep(800);
						}

						if (!list.Fields.ContainsField("SLAM ID"))
						{
							SPField newField = rootSite.Fields["SLAM ID"];
							SPAddFieldOptions fieldOptions = SPAddFieldOptions.AddToAllContentTypes;
							if (!list.ContentTypesEnabled)
							{
								fieldOptions = SPAddFieldOptions.AddToDefaultContentType;
							}
							list.Fields.AddFieldAsXml(newField.SchemaXml, false, fieldOptions);
							list.Update();
						}
					}
					site.Dispose();
					rootSite.Dispose();
				}
			}
		}

		public void RemoveSlamIdFieldToList(string siteCollectionUrl, string siteName, string listId, string listName)
		{
			using (SPSite siteCollection = new SPSite(siteCollectionUrl))
			{
				SPWeb site = null;
				if (String.IsNullOrEmpty(siteName))
				{
					site = siteCollection.RootWeb;
				}
				else
				{
					try
					{
						site = siteCollection.AllWebs[siteName];
					}
					catch { }
				}

				SPList list = null;

				if (site != null && site.Exists)
				{
					site.AllowUnsafeUpdates = true;

					try
					{
						if (!String.IsNullOrEmpty(listId))
						{
							list = site.Lists[new Guid(listId)];
						}
						else
						{
							list = site.Lists[listName];
						}
					}
					catch { }

					if (list != null && list.Fields.ContainsField("SLAM ID"))
					{
						SPField field = list.Fields["SLAM ID"];
						field.Hidden = false;
						field.Update();
						list.Update();

						field = list.Fields["SLAM ID"];
						field.Delete();
						list.Update();
					}

					site.Dispose();
				}
			}
		}

		public void AttachContentTypeEventHandler(string siteCollectionUrl, string siteName, string contentTypeName, SPEventReceiverType eventReceiverType, string assemblyName, string className)
		{
			using (SPSite siteCollection = new SPSite(siteCollectionUrl))
			{
				SPWeb site = null;
				if (String.IsNullOrEmpty(siteName))
				{
					site = siteCollection.RootWeb;
				}
				else
				{
					try
					{
						site = siteCollection.AllWebs[siteName];
					}
					catch { }
				}

				if (site != null && site.Exists)
				{
					site.AllowUnsafeUpdates = true;

					SPContentType contentType = null;

					try
					{
						contentType = site.ContentTypes[contentTypeName];
					}
					catch
					{
						//content type not found
					}

					if (contentType != null)
					{
						//verify event receiver is not duplicate
						bool exists = false;
						foreach (SPEventReceiverDefinition receiver in contentType.EventReceivers)
						{
							if (receiver.Name == "SLAM" + siteName + contentTypeName + eventReceiverType.ToString())
							{
								exists = true;
								break;
							}
						}
						if (!exists)
						{
							string receiverName = "SLAM" + siteName + contentTypeName + eventReceiverType.ToString();
							SPEventReceiverDefinition eventReceiver = contentType.EventReceivers.Add();
							eventReceiver.Name = receiverName;
							eventReceiver.Synchronization = SPEventReceiverSynchronization.Synchronous;
							eventReceiver.Assembly = assemblyName;
							eventReceiver.Class = className;
							eventReceiver.Type = eventReceiverType;
							eventReceiver.SequenceNumber = _sequenceNumber;
							eventReceiver.Data = contentTypeName;
							eventReceiver.Update();
							contentType.Update(true, false);

							_sequenceNumber++;
						}

					}

					site.Dispose();
				}
			}
		}

		public void AttachContentTypeEventHandlers(string siteCollectionUrl, string siteName, string contentTypeName, SPEventReceiverType[] eventReceiverTypes, string assemblyName, string className)
		{
			using (SPSite siteCollection = new SPSite(siteCollectionUrl))
			{
				SPWeb site = null;
				if (String.IsNullOrEmpty(siteName))
				{
					site = siteCollection.RootWeb;
				}
				else
				{
					try
					{
						site = siteCollection.AllWebs[siteName];
					}
					catch { }
				}

				if (site != null && site.Exists)
				{
					site.AllowUnsafeUpdates = true;

					SPContentType contentType = null;

					try
					{
						contentType = site.ContentTypes[contentTypeName];
					}
					catch
					{
						//content type not found
					}

					if (contentType != null)
					{
						//verify event receiver is not duplicate
						bool exists = false;
						bool requiresUpdate = false;
						List<string> eventReceiversAdded = new List<string>();
						foreach (SPEventReceiverType eventReceiverType in eventReceiverTypes)
						{
							foreach (SPEventReceiverDefinition receiver in contentType.EventReceivers)
							{
								if (receiver.Name == "SLAM" + siteName + contentTypeName + eventReceiverType.ToString())
								{
									exists = true;
									break;
								}
							}

							if (!exists)
							{
								string receiverName = "SLAM" + siteName + contentTypeName + eventReceiverType.ToString();
								SPEventReceiverDefinition eventReceiver = contentType.EventReceivers.Add();
								eventReceiver.Name = receiverName;
								eventReceiver.Assembly = assemblyName;
								eventReceiver.Class = className;
								eventReceiver.Type = eventReceiverType;
								eventReceiver.Synchronization = SPEventReceiverSynchronization.Synchronous;
								eventReceiver.SequenceNumber = _sequenceNumber;
								eventReceiver.Data = contentTypeName;
								eventReceiver.Update();
								requiresUpdate = true;
								_sequenceNumber++;
								eventReceiversAdded.Add(receiverName);
							}
							exists = false;
						}
						if (requiresUpdate)
						{
							try
							{
								contentType.Update(true, false);

								using (SPWeb contentTypeSite = siteCollection.AllWebs[site.ID])
								{
									//Though changes were pushed to children, not all children
									//should receive updates, namely child site content types
									foreach (SPContentType siteContentType in contentTypeSite.ContentTypes)
									{
										if (siteContentType.Parent.Id.Equals(contentType.Id))
										{
											bool updateContentType = false;
											for (int i = 0; i < siteContentType.EventReceivers.Count; i++)
											{
												if (eventReceiversAdded.Contains(siteContentType.EventReceivers[i].Name))
												{
													siteContentType.EventReceivers[i].Delete();
													i--;
													updateContentType = true;
												}
											}

											if (updateContentType)
											{
												siteContentType.Update(true, false);
											}
										}
									}
								}
							}
							catch
							{
								using (SPWeb newSite = siteCollection.AllWebs[site.ID])
								{
									contentType = newSite.ContentTypes[contentTypeName];
									newSite.AllowUnsafeUpdates = true;
									contentType.Update(true, false);

									using (SPWeb contentTypeSite = siteCollection.AllWebs[site.ID])
									{
										//Though changes were pushed to children, not all children
										//should receive updates, namely child site content types
										foreach (SPContentType siteContentType in contentTypeSite.ContentTypes)
										{
											if (siteContentType.Parent.Id.Equals(contentType.Id))
											{
												bool updateContentType = false;
												for (int i = 0; i < siteContentType.EventReceivers.Count; i++)
												{
													if (eventReceiversAdded.Contains(contentType.EventReceivers[i].Name))
													{
														siteContentType.EventReceivers[i].Delete();
														i--;
														updateContentType = true;
													}
												}

												if (updateContentType)
												{
													siteContentType.Update(true, false);
												}
											}
										}
									}
								}
							}
						}
					}

					site.Dispose();
				}
			}
		}

		public void AttachListEventHandler(string siteCollectionUrl, string siteName, string listId, string listName, SPEventReceiverType eventReceiverType, string assemblyName, string className)
		{
			using (SPSite siteCollection = new SPSite(siteCollectionUrl))
			{
				SPWeb site = null;
				if (String.IsNullOrEmpty(siteName) || siteName == "*")
				{
					site = siteCollection.RootWeb;
				}
				else
				{
					try
					{
						site = siteCollection.AllWebs[siteName];
					}
					catch { }
				}

				SPList list = null;
				bool exists = false;

				if (site != null && site.Exists)
				{
					site.AllowUnsafeUpdates = true;

					try
					{
						if (!String.IsNullOrEmpty(listId))
						{
							list = site.Lists[new Guid(listId)];
						}
						else
						{
							list = site.Lists[listName];
						}
					}
					catch { }

					if (list != null)
					{
						//verify event receiver is not duplicate
						foreach (SPEventReceiverDefinition receiver in list.EventReceivers)
						{
							if (receiver.Name == "SLAM" + siteName + listName + eventReceiverType.ToString())
							{
								exists = true;
								break;
							}
						}

						if (!exists)
						{
							SPEventReceiverDefinition eventReceiver = list.EventReceivers.Add();
							eventReceiver.Name = "SLAM" + siteName + listName + eventReceiverType.ToString();
							eventReceiver.Assembly = assemblyName;
							eventReceiver.Class = className;
							eventReceiver.Type = eventReceiverType;
							eventReceiver.Synchronization = SPEventReceiverSynchronization.Synchronous;
							eventReceiver.SequenceNumber = _sequenceNumber;
							eventReceiver.Update();
							list.Update();

							_sequenceNumber++;
						}
					}
					site.Dispose();
				}

				if (siteName == "*")
				{
					foreach (SPWeb nextWeb in site.Site.AllWebs)
					{
						try
						{
							list = null;
							list = nextWeb.Lists[listName];

							//verify event receiver is not duplicate
							exists = false;
							foreach (SPEventReceiverDefinition receiver in list.EventReceivers)
							{
								if (receiver.Name == "SLAM" + siteName + listName + eventReceiverType.ToString())
								{
									exists = true;
									break;
								}
							}
							if (!exists)
							{
								site.AllowUnsafeUpdates = true;

								SPEventReceiverDefinition eventReceiver = list.EventReceivers.Add();
								eventReceiver.Name = "SLAM" + siteName + listName + eventReceiverType.ToString();
								eventReceiver.Assembly = assemblyName;
								eventReceiver.Class = className;
								eventReceiver.Type = eventReceiverType;
								eventReceiver.SequenceNumber = _sequenceNumber;
								eventReceiver.Update();
								//list.EventReceivers.Add(eventReceiverType, assemblyName, className);
								list.Update();

								_sequenceNumber++;
							}
						}
						catch { }
						nextWeb.Dispose();
					}
				}
			}
		}

		/// <summary>
		/// Creates a new ContentType with the given name and collection of fields.
		/// </summary>
		/// <param name="contentTypeName"></param>
		/// <param name="fields"></param>
		/// <returns></returns>
		public bool CreateContentType(string siteCollectionUrl, string siteName, string contentTypeName, IEnumerable<Field> fields)
		{
			bool success = true;
			using (SPSite siteCollection = new SPSite(siteCollectionUrl))
			{
				SPWeb site = null;
				if (String.IsNullOrEmpty(siteName))
				{
					site = siteCollection.RootWeb;
				}
				else
				{
					site = siteCollection.AllWebs[siteName];
				}

				if (site != null && site.Exists)
				{
					site.AllowUnsafeUpdates = true;
					try
					{

						SPContentType itemContentType = site.AvailableContentTypes["Item"];
						SPContentType newContentType = new SPContentType(itemContentType, site.ContentTypes, contentTypeName);
						newContentType.Group = "List Content Types";
						site.ContentTypes.Add(newContentType);
						site.Update();

						foreach (Field newField in fields)
						{
							if (TypeDescriptor.GetProperties(newContentType).Find(newField.Name, true) == null)
							{
								SPField addField = null;
								if (!site.Fields.ContainsField(newField.Name))
								{
									addField = site.Fields.CreateNewField(newField.SharePointType, newField.Name);
									site.Fields.Add(addField);
									site.Update();
								}

								SPFieldLink fieldLink = new SPFieldLink(site.Fields[newField.Name]);
								//fieldLink.Required = newField.Required;
								newContentType.FieldLinks.Add(fieldLink);
								newContentType.Update();
							}
						}
					}
					catch
					{
						success = false;
					}

					site.Dispose();
				}
			}
			return success;
		}

		/// <summary>
		/// Creates a new List with the given name and collection of fields.
		/// </summary>
		/// <param name="listName"></param>
		/// <param name="fields"></param>
		/// <returns></returns>
		public bool CreateList(string siteName, string listName, IEnumerable fields)
		{
			throw new NotImplementedException();
		}

		public void DetachAllEventHandlers(string siteCollectionUrl, string assemblyName, string listClassName, string contentTypeClassName)
		{
			TraceLevel currentTraceLevel = TraceLevel.Error;

			//Check if the logger is the default SqlLogger
			SqlLogger sqlLogger = _logger is SqlLogger ? ((SqlLogger)_logger) : null;
			//If it is, force it to log Activation's messages regardless of the
			//configured trace level
			if (sqlLogger != null)
			{
				currentTraceLevel = sqlLogger.Switch.Level;
				sqlLogger.Switch.Level = TraceLevel.Verbose;
			}

			using (SPSite siteCollection = new SPSite(siteCollectionUrl))
			{
				foreach (SPWeb site in siteCollection.AllWebs)
				{
					site.AllowUnsafeUpdates = true;

					bool performLogMessage = false;

					//Detach all event handlers for content types within this site
					for (int c = 0; c < site.ContentTypes.Count; c++)
					{
						//This is a little ridiculous, but because we are using
						//contentType.Update(true, false) to propagate the event receiver deletion to
						//the children of this content type without the "innerSite" here opened for every one
						//this process will throw an exception with the message:
						//"The object has been updated by another user since it was last fetched"
						using (SPWeb innerSite = siteCollection.OpenWeb(site.ID))
						{
							SPContentType contentType = innerSite.ContentTypes[site.ContentTypes[c].Id];
							if (!contentType.Sealed && !contentType.ReadOnly)
							{
								bool updateContentType = false;
								for (int i = 0; i < contentType.EventReceivers.Count; i++)
								{
									//Check if the assembly name, at the beginning, and the PublicKeyToken, at the end
									//of the full Assembly name matches.  This should detach event handlers
									//from old versions.
									if ((contentType.EventReceivers[i].Assembly.StartsWith(assemblyName.Substring(0, assemblyName.IndexOf(",")))) ||
										contentType.EventReceivers[i].Name.StartsWith("SLAM"))
									{
										contentType.EventReceivers[i].Delete();
										i--;
										performLogMessage = true;
										updateContentType = true;
									}
								}

								if (updateContentType)
								{
									innerSite.AllowUnsafeUpdates = true;
									try
									{
										contentType.Update(true, true);
									}
									catch
									{
										contentType.Update(false, false);
									}
								}

								if (performLogMessage)
								{
									string typeString = "";
									if (String.IsNullOrEmpty(site.ServerRelativeUrl.TrimEnd('/')))
									{
										typeString = String.Format("{0} - {1}", site.ServerRelativeUrl.TrimEnd('/'), contentType.Name);
									}
									else
									{
										typeString = contentType.Name;
									}
									_logger.LogMessage("Information", "Detached Event Handlers for Content Type: " + typeString);
								}

								performLogMessage = false;
							}
						}
					}

					//Detach all event handlers for Lists within this site
					for (int l = 0; l < site.Lists.Count; l++)
					{
						SPList list = site.Lists[l];
						for (int i = 0; i < list.EventReceivers.Count; i++)
						{
							//Check if the assembly name, at the beginning, and the PublicKeyToken, at the end
							//of the full Assembly name matches.  This should detach event handlers
							//from old versions.
							if ((list.EventReceivers[i].Assembly.StartsWith(assemblyName.Substring(0, assemblyName.IndexOf(",")))) ||
								list.EventReceivers[i].Name.StartsWith("SLAM"))
							{
								list.EventReceivers[i].Delete();
								i--;
								performLogMessage = true;
							}
						}

						list.Update();

						if (performLogMessage)
						{
							string typeString = "";
							if (String.IsNullOrEmpty(site.ServerRelativeUrl.TrimEnd('/')))
							{
								typeString = String.Format("{0} - {1} - {2}", site.ServerRelativeUrl.TrimEnd('/'), list.ID.ToString(), list.Title);
							}
							else
							{
								typeString = String.Format("{0} - {1}", list.ID.ToString(), list.Title);
							}
							_logger.LogMessage("Information", "Detached Event Handlers for List: " + typeString);
						}

						performLogMessage = false;
					}

					site.Dispose();
				}
			}
		}

		public void DetachContentTypeEventHandlers(string siteCollectionUrl, string siteName, string contentTypeName, string assemblyName, string className)
		{
			using (SPSite siteCollection = new SPSite(siteCollectionUrl))
			{
				SPWeb site = null;
				if (String.IsNullOrEmpty(siteName))
				{
					site = siteCollection.RootWeb;
				}
				else
				{
					site = siteCollection.AllWebs[siteName];
				}

				if (site != null && site.Exists)
				{
					site.AllowUnsafeUpdates = true;

					SPContentType contentType = site.ContentTypes[contentTypeName];

					bool updateContentType = false;
					for (int i = 0; i < contentType.EventReceivers.Count; i++)
					{
						//Check if the assembly name, at the beginning, and the PublicKeyToken, at the end
						//of the full Assembly name matches.  This should detach event handlers
						//from old versions.
						if ((contentType.EventReceivers[i].Assembly.StartsWith(assemblyName.Substring(0, assemblyName.IndexOf(",") + 1)) &&
							contentType.EventReceivers[i].Assembly.EndsWith(assemblyName.Substring(assemblyName.LastIndexOf(",") + 1)) &&
							contentType.EventReceivers[i].Class == className) ||
							contentType.EventReceivers[i].Name.StartsWith("SLAM"))
						{
							contentType.EventReceivers[i].Delete();
							i--;
							updateContentType = true;
						}
					}

					if (updateContentType)
					{
						contentType.Update(true, false);
					}
					site.Dispose();
				}
			}
		}

		public void DetachListContentTypeEventHandlers(string siteCollectionUrl, string siteName, string listId, string listName, string assemblyName, string className)
		{
			using (SPSite siteCollection = new SPSite(siteCollectionUrl))
			{

				SPWeb site = null;
				if (String.IsNullOrEmpty(siteName))
				{
					site = siteCollection.RootWeb;
				}
				else
				{
					site = siteCollection.AllWebs[siteName];
				}

				if (site != null && site.Exists)
				{
					site.AllowUnsafeUpdates = true;

					SPList list = null;
					try
					{
						if (!String.IsNullOrEmpty(listId))
						{
							list = site.Lists[new Guid(listId)];
						}
						else
						{
							list = site.Lists[listName];
						}
					}
					catch { }

					if (list != null)
					{
						foreach (SPContentType contentType in list.ContentTypes)
						{
							bool updateContentType = false;
							for (int i = 0; i < contentType.EventReceivers.Count; i++)
							{
								//Check if the assembly name, at the beginning, and the PublicKeyToken, at the end
								//of the full Assembly name matches.  This should detach event handlers
								//from old versions.
								if ((contentType.EventReceivers[i].Assembly.StartsWith(assemblyName.Substring(0, assemblyName.IndexOf(",") + 1)) &&
									contentType.EventReceivers[i].Assembly.EndsWith(assemblyName.Substring(assemblyName.LastIndexOf(",") + 1)) &&
									contentType.EventReceivers[i].Class == className) ||
									contentType.EventReceivers[i].Name.StartsWith("SLAM"))
								{
									contentType.EventReceivers[i].Delete();
									i--;
									updateContentType = true;
								}
							}

							if (updateContentType)
							{
								contentType.Update(true, false);
							}
						}

						list.Update();
					}

					site.Dispose();
				}
			}
		}

		public void DetachListEventHandlers(string siteCollectionUrl, string siteName, string listId, string listName, string assemblyName, string className)
		{
			using (SPSite siteCollection = new SPSite(siteCollectionUrl))
			{
				SPWeb site = null;
				try
				{
					if (String.IsNullOrEmpty(siteName) || siteName == "*")
					{
						site = siteCollection.RootWeb;
					}
					else
					{
						site = siteCollection.AllWebs[siteName];
					}
				}
				catch { }

				if (site != null)
				{
					SPList list = null;

					if (site.Exists)
					{
						site.AllowUnsafeUpdates = true;

						try
						{
							if (!String.IsNullOrEmpty(listId))
							{
								list = site.Lists[new Guid(listId)];
							}
							else
							{
								list = site.Lists[listName];
							}
						}
						catch { }
						if (list != null)
						{
							for (int i = 0; i < list.EventReceivers.Count; i++)
							{
								//Check if the assembly name, at the beginning, and the PublicKeyToken, at the end
								//of the full Assembly name matches.  This should detach event handlers
								//from old versions.
								if ((list.EventReceivers[i].Assembly.StartsWith(assemblyName.Substring(0, assemblyName.IndexOf(",") + 1)) &&
									list.EventReceivers[i].Assembly.EndsWith(assemblyName.Substring(assemblyName.LastIndexOf(",") + 1)) &&
									list.EventReceivers[i].Class == className) ||
									list.EventReceivers[i].Name.StartsWith("SLAM"))
								{
									list.EventReceivers[i].Delete();
									i--;
								}
							}

							list.Update();
						}



						if (siteName == "*")
						{
							foreach (SPWeb nextWeb in site.Site.AllWebs)
							{
								try
								{
									list = null;
									try
									{
										if (!String.IsNullOrEmpty(listId))
										{
											list = nextWeb.Lists[new Guid(listId)];
										}
										else
										{
											list = nextWeb.Lists[listName];
										}
									}
									catch { }
									if (list != null)
									{
										for (int i = 0; i < list.EventReceivers.Count; i++)
										{
											if (list.EventReceivers[i].Assembly == assemblyName && list.EventReceivers[i].Class == className)
											{
												list.EventReceivers[i].Delete();
												i--;
											}
										}

										list.Update();
									}
								}
								catch { }
								nextWeb.Dispose();
							}
						}

						site.Dispose();
					}
				}
			}
		}

		public bool VerifyContentTypeExists(string siteCollectionUrl, string siteName, string contentTypeName)
		{
			bool contentTypeExists = true;

			using (SPSite siteCollection = new SPSite(siteCollectionUrl))
			{
				SPWeb site = null;
				if (String.IsNullOrEmpty(siteName))
				{
					site = siteCollection.RootWeb;
				}
				else
				{
					site = siteCollection.AllWebs[siteName];
				}

				try
				{
					contentTypeExists = site.ContentTypes[contentTypeName] != null;
				}
				catch
				{
					contentTypeExists = false;
				}

				site.Dispose();
			}
			return contentTypeExists;
		}

		public bool VerifyListExists(string siteCollectionUrl, string siteName, string listName)
		{
			bool listExists = true;

			using (SPSite siteCollection = new SPSite(siteCollectionUrl))
			{
				SPWeb site = null;
				if (String.IsNullOrEmpty(siteName))
				{
					site = siteCollection.RootWeb;
				}
				else
				{
					site = siteCollection.AllWebs[siteName];
				}

				try
				{
					listExists = site.Lists[listName] != null;
				}
				catch
				{
					listExists = false;
				}

				site.Dispose();
			}
			return listExists;
		}
	}
}
